package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.dto.ReservationDto;
import com.zzyl.dto.VisitDto;
import com.zzyl.entity.CountTime;
import com.zzyl.entity.Member;
import com.zzyl.entity.Reservation;
import com.zzyl.enums.BasicEnum;
import com.zzyl.enums.ReservationStatus;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ReservationMapper;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.service.ReservationService;
import com.zzyl.service.VisitService;
import com.zzyl.utils.UserThreadLocal;
import com.zzyl.vo.ReservationVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ReservationServiceImpl implements ReservationService {
    @Autowired
    private ReservationMapper reservationMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private VisitService visitService;

    /**
     * 小程序查询取消预约次数
     * @return
     */
    @Override
    public Integer getCount() {
        //获取当前请求线程中的用户ID
        Long userId = UserThreadLocal.getUserId();
//        //查询微信登录用户信息
//        Member member = memberMapper.selectWechatUserById(userId);
//        String phone = member.getPhone();

        //查询取消预约记录
        List<Reservation> reservations = reservationMapper.selectReservation(userId);
        //获取取消次数
        int count = reservations.size();
        return count;
    }


    /**
     * 查询每个时间段剩余预约次数
     * @param time
     * @return
     */
    @Override
    public List<CountTime> getCountByTime(Long time) {
        //校验参数
        if (time == null) {
            throw new BaseException(BasicEnum.PARAM_ERROR);
        }
        //将时间戳毫秒值转为日期格式
        LocalDateTime startTime = LocalDateTimeUtil.of(time);
        LocalDateTime endTime = startTime.plusHours(24);
        //查询预约时间段剩余次数
        List<CountTime> countByTimes = reservationMapper.selectCountByTime(startTime,endTime);
        return countByTimes;
    }

    /**
     * 小程序新增预约参观
     * @param reservationDto
     */
    @Override
    public void addReservation(ReservationDto reservationDto) {
        if (reservationDto == null) {
            throw new BaseException(BasicEnum.PARAM_ERROR);
        }
        //如果该用户已经取消过3次预约，则不能添加预约
        Long userId = UserThreadLocal.getUserId();
        if (reservationMapper.selectReservation(userId).size() >= 3) {
            throw new BaseException(BasicEnum.RESERVATION_CANCEL_COUNT_UPPER_LIMIT);
        }
        Reservation reservation = BeanUtil.toBean(reservationDto, Reservation.class);
        reservation.setStatus(0); //默认状态为未报到
        //新增预约参观
        reservationMapper.insert(reservation);
    }

    /**
     * 小程序分页查询预约参观
     * @param pageNum
     * @param pageSize
     * @param status
     * @return
     */
    @Override
    public PageResponse<ReservationVo> getList(Integer pageNum, Integer pageSize, Integer status) {
        if (pageNum == null || pageSize == null) {
            throw new BaseException(BasicEnum.PARAM_ERROR);
        }
        //获取到当前请求线程中用户ID
        Long userId = UserThreadLocal.getUserId();
        //设置起始页码
        PageHelper.startPage(pageNum,pageSize);
        //查询预约列表
        Page<ReservationVo> reservationVos = reservationMapper.selectList(status,userId);
        //返回分页结果
        return PageResponse.of(reservationVos,ReservationVo.class);
    }


    /**
     * 小程序端用户取消预约
     * @param id
     */
    @Override
    public void updateById(Long id) {
        if (id == null) {
            throw new BaseException(BasicEnum.PARAM_ERROR);
        }
        Reservation reservation = new Reservation();
        reservation.setId(id);
        reservation.setStatus(2);
        //取消预约，更新操作
        reservationMapper.updateById(reservation);
    }

    @Override
    public void update(Long id, ReservationDto dto) {
        Reservation reservation = reservationMapper.findById(id);
        if (reservation != null) {
            BeanUtils.copyProperties(dto, reservation);
            reservation.setId(id);
            reservation.setUpdateTime(LocalDateTime.now());
            reservationMapper.update(reservation);
        }
    }

    @Override
    public void deleteById(Long id) {
        reservationMapper.deleteById(id);
    }

    @Override
    public void visit(Long id, Long time) {
        Reservation reservation = reservationMapper.findById(id);
        if (reservation != null) {
            reservation.setStatus(ReservationStatus.COMPLETED.getOrdinal());
            reservationMapper.update(reservation);
            VisitDto visitDto = BeanUtil.toBean(reservation, VisitDto.class);
            visitDto.setTime(LocalDateTimeUtil.of(time));
            visitService.add(visitDto);
        }
    }

    @Override
    public ReservationVo findById(Long id) {
        Reservation reservation = reservationMapper.findById(id);
        if (reservation != null) {
            return convertToVO(reservation);
        }
        return null;
    }

    @Override
    public List<ReservationVo> findAll(String mobile, LocalDateTime time) {
        LocalDateTime endTime = time.plusHours(24); // 计算24小时后的时间
        Long userId = UserThreadLocal.getUserId();
        List<Reservation> reservations = reservationMapper.findAll(userId, mobile, time, endTime); // 根据mobile和时间范围查询预约
        return convertToVOList(reservations);
    }

    @Override
    public PageResponse<ReservationVo> findByPage(int pageNum, int pageSize, String name, String phone, Integer status, Integer type, LocalDateTime startTime, LocalDateTime endTime) {
        PageHelper.startPage(pageNum, pageSize);
        Long userId = UserThreadLocal.getUserId();
        Page<Reservation> byPage = reservationMapper.findByPage(pageNum, pageSize, name, phone, status, type, userId, startTime, endTime);
        return PageResponse.of(byPage, ReservationVo.class);
    }

    /**
     * 将Reservation转换为ReservationVO
     */
    private ReservationVo convertToVO(Reservation reservation) {
        return BeanUtil.toBean(reservation, ReservationVo.class);
    }

    /**
     * 将时间戳转换为字符串
     */
    private String convertTimeToStr(Long time) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time));
    }

    /**
     * 将List<Reservation>转换为List<ReservationVO>
     */
    private List<ReservationVo> convertToVOList(List<Reservation> reservations) {
        return reservations.stream().map(this::convertToVO).collect(Collectors.toList());
    }
}
